package com.example.caffeinecache01.config;

import com.github.benmanes.caffeine.cache.Caffeine;

import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.cache.caffeine.CaffeineCache;
import org.springframework.cache.caffeine.CaffeineCacheManager;
import java.util.concurrent.TimeUnit;


/**
 * initialCapacity=[integer]: 初始的缓存空间大小
 * maximumSize=[long]: 缓存的最大条数
 * maximumWeight=[long]: 缓存的最大权重
 * expireAfterAccess=[duration]: 最后一次写入或访问后经过固定时间过期
 * expireAfterWrite=[duration]: 最后一次写入后经过固定时间过期
 * refreshAfterWrite=[duration]: 创建缓存或者最近一次更新缓存后经过固定的时间间隔，刷新缓存
 * weakKeys: 打开key的弱引用
 * weakValues：打开value的弱引用
 * softValues：打开value的软引用
 * recordStats：开发统计功能 注意：
 * expireAfterWrite和expireAfterAccess同事存在时，以expireAfterWrite为准。
 * maximumSize和maximumWeight不可以同时使用
 * weakValues和softValues不可以同时使用
 */
@Configuration
@EnableCaching
public class CaffeineCacheConfig {
    @Bean
    public CacheManager cacheManager(){
        CaffeineCacheManager  cacheManager = new CaffeineCacheManager();
        //Caffeine配置
        Caffeine<Object, Object> caffeine = Caffeine.newBuilder()
                                            //最后一次写入后经过固定时间过期
                                            .expireAfterWrite(10, TimeUnit.SECONDS)
                                            //maximumSize=[long]: 缓存的最大条数
                                            .maximumSize(1000);
        cacheManager.setCaffeine(caffeine);
        return cacheManager;
    }



//     @Value("${caffeine.spec}")
//     private String caffeineSpec;
//
//     @Autowired
//     private CacheLoader cacheLoader;
//
//
//     @Bean
//     public CacheManager cacheManagerWithCacheLoading(){
//         logger.info("cacheManagerWithCacheLoading" );
//         Caffeine caffeine = Caffeine.newBuilder()
//                 .initialCapacity(100)
//                 .maximumSize(1000)
// //                .refreshAfterWrite(5,TimeUnit.SECONDS)
//                 .expireAfterWrite(50,TimeUnit.SECONDS);
//
//         CaffeineCacheManager cacheManager = new CaffeineCacheManager();
//         cacheManager.setAllowNullValues(true);
//         cacheManager.setCaffeine(caffeine);
// //        cacheManager.setCacheLoader(cacheLoader);
//         cacheManager.setCacheNames(getNames());
//         return cacheManager;
//     }



//     @Bean(name = "caffeine")
//     @Primary
//     public CacheManager cacheManagerWithCaffeine(){
//         logger.info("This is cacheManagerWithCaffeine");
//         CaffeineCacheManager cacheManager = new CaffeineCacheManager();
//         Caffeine caffeine = Caffeine.newBuilder()
//                 //cache的初始容量值
//                 .initialCapacity(100)
//                 //maximumSize用来控制cache的最大缓存数量，maximumSize和maximumWeight不可以同时使用，
//                 .maximumSize(1000);
//         //控制最大权重
// //                .maximumWeight(100);
// //                .expireAfter();
//         //使用refreshAfterWrite必须要设置cacheLoader
// //                .refreshAfterWrite(5,TimeUnit.SECONDS);
//         cacheManager.setCaffeine(caffeine);
// //        cacheManager.setCacheLoader(cacheLoader);
//         cacheManager.setCacheNames(getNames());
// //        cacheManager.setAllowNullValues(false);
//         return cacheManager;
//     }

//     @Bean(name = "caffeineSpec")
//     public CacheManager cacheManagerWithCaffeineFromSpec(){
//         CaffeineSpec spec = CaffeineSpec.parse(caffeineSpec);
//         Caffeine caffeine = Caffeine.from(spec);
//         //此方法等同于上面from(spec)
// //        Caffeine caffeine = Caffeine.from(caffeineSpec);
//
//         CaffeineCacheManager cacheManager = new CaffeineCacheManager();
//         cacheManager.setCaffeine(caffeine);
//         cacheManager.setCacheNames(getNames());
//         return cacheManager;
//     }
//
//     private static List<String> getNames(){
//         List<String> names = new ArrayList<>(2);
//         names.add("outLimit");
//         names.add("notOutLimit");
//         return names;
//     }

}